package client;

import model.FileInfo;
import model.NodeElement;
import model.ProgConsumer;
import model.Programs;
import session.ClientSession;
import session.SessionListen;
import view.ChatView;
import view.FileView;
import view.ProgramView;
import view.UserLoginView;

import model.Program;

import model.ProgConsumer;

import com.sun.media.jsdt.Channel;
import com.sun.media.jsdt.Client;
import com.sun.media.jsdt.Data;
import com.sun.media.jsdt.JSDTException;
import com.sun.media.jsdt.Session;
import com.sun.media.jsdt.SessionFactory;
import com.sun.media.jsdt.URLString;

import controller.FileController;

public class ClientUser {
	private Session session;
	private Client client;
	private Channel channel;
	private String login;
	private boolean isConnected;
	private ProgConsumer progConsumer;
	private FileController fileController;
	private ProgramView programView;
	private FileView fileView;
	private FileInfo fileInfo;
	private Programs programs;
	private NodeElement nodeInfoSelected_Tmp;

	private Channel channelChat;
	private Channel channelProg;
	private Channel channelFile;
	private int hostport = 8888;
	private ChatView chatView;
	private UserLoginView userLoginView;
	
	public Channel getChannelChat() {
		return channelChat;
	}
	public void setCanalChat(Channel channelChat) {
		this.channelChat = channelChat;
	}

	
	public Channel getChannelProg() {
		return channelProg;
	}
	public void setChannelProg(Channel channelProg) {
		this.channelProg = channelProg;
	}

	
	public ClientUser(){

    	
	}
	public void start(){
		this.isConnected = false;
    	this.userLoginView = new UserLoginView(this);
    	this.userLoginView.pack();
    	this.userLoginView.setVisible(true);
	}

	public void joinSession(){
		boolean error = true;
		this.client = new ClientSession(getLogin());
		while (error) {
			URLString url = URLString.createSessionURL("localhost", hostport,
					"socket", "userSession");
			System.out.println(url);
			try {
				// Connexion a la session
				this.session = SessionFactory.createSession(getClient(), url,false);
				this.session.addSessionListener(new SessionListen(this));
				this.session.join(this.client);

//				/* Create a chat client. */
				 this.channelChat = this.session.createChannel(getClient(),
				 "CANAL_CHAT", true, true, true);

				 this.channelProg = this.session.createChannel(getClient(),
				 "CANAL_PROG", true, true, true);
				 
				 this.channelFile = this.session.createChannel(getClient(),"CANAL_FILE",true,true,true);
				 

				// Le client est connecte
				this.isConnected = true;
				System.out.println("ClientUser " + getLogin()
						+ " :: Connexion reussi");
				error = false;
				
			} catch (JSDTException ex) {
				if (ex.toString().equals("port in use")) {
					error = true;
					this.hostport++;
				} else {
					System.out.println("ClientUser " + getLogin()
							+ " :: Impossible de lancer la session");
					error = false;
					ex.printStackTrace();
				}
			}
		}
		if(isConnected()){
			this.userLoginView.setVisible(false);
	        fileView = new FileView(getClient().getName(),new FileController(this));
	        //nodeInfoSelected_Tmp = new NodeElement("Nom", "Type"); 
	        this.programs = new Programs();
	        initialLesProgrammes();
	        fileController = new FileController(this);
	        fileController.setFileView(fileView);
	        fileController.initialProgrammes(this.programs);
	        fileController.setChatView(chatView);
	        fileController.addChanelProgConsumer();
	        
	        addNewUserToTree(getClient().getName());
	        initTreeFromListClientNames();
			
	        chatView = new ChatView(this);
	        initComboBoxFromListClientNames();
	        
			programView = new ProgramView(this);
			programView.setUser(getLogin());
			programView.setFileView(fileView);
			programView.setChatView(chatView);
			programView.initialize();
			
			
				
//		     progConsumer = new ProgConsumer(fileController,chatView);
//		        try {
//		        	channelProg.addConsumer(getClient(), progConsumer);
//		        	Program prog = this.nodeInfoSelected_Tmp.getProgram();
//		            Data data = new Data(prog);
//		            data.setPriority(Channel.HIGH_PRIORITY);
//		            getChannelProg().sendToAll(getClient(), data);
//				} catch (JSDTException e) {
//					// TODO Auto-generated catch block
//					e.printStackTrace();
//				}
		}
		
	}

	public void initComboBoxFromListClientNames(){
		String[] listClientNames = getListClientNames();
		chatView.initListClients(listClientNames, this.getClient().getName());
	}

	
	public void initTreeFromListClientNames(){
		String[] listClientNames = getListClientNames();
		fileController.initTreeFromListClientNames(listClientNames, this.getClient().getName());
	}
	
    public void addNewUserToTree(String userName){
    	this.fileController.addNewUserToTreePerso(userName);
    	this.fileController.addNewUserToTreePartage(userName);
    }
	
	public String[] getListClientNames(){
	      String[] listeClient = null;
			try {
				listeClient = getSession().listClientNames();
			} catch (JSDTException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return listeClient;
	}
	
	public void initialLesProgrammes(){
		String code = "avancer(50);\ndroite(90);\navancer(50);\ndroite(90);\n" +
		"avancer(50);\ndroite(90);\navancer(50);\ndroite(135);\n" +
		"avancer(25);\ndroite(45);\navancer(50);\ndroite(135);\navancer(25);\ndroite(135);\navancer(50);\ndroite(45);\navancer(25);";
		
		Program prog = new Program("src", "program1", getClient().getName());
		prog.setSrc(code);
		this.programs.addProgram(prog);
		/*
		code = "avancer(30);\ndroite(90);\navancer(50);\ndroite(90);\n" +
		"avancer(50);\ndroite(90);\navancer(50);\nlever();\ndroite(90);\n" +
		"avancer(50);\nbaisser();";
		prog = new Program("src", "program2", this.clientView.getClientName());
		prog.setSrc(code);
		this.programs.addProgram(prog);
		*/
		code = "avancer(50);\ndroite(90);avancer(150);\ndroite(90);\navancer(50);\ndroite(90);" +
				"\navancer(150);\ndroite(90);";
		prog = new Program("src", "program2", getClient().getName());
		prog.setSrc(code);
		this.programs.addProgram(prog);
	}

	/**
	 * @param login the login to set
	 */
	public void setLogin(String login) {
		this.login = login;
	}

	/**
	 * @return the login
	 */
	public String getLogin() {
		return login;
	}



	/**
	 * @param session the session to set
	 */
	public void setSession(Session session) {
		this.session = session;
	}



	/**
	 * @return the session
	 */
	public Session getSession() {
		return session;
	}



	/**
	 * @param client the client to set
	 */
	public void setClient(Client client) {
		this.client = client;
	}



	/**
	 * @return the client
	 */
	public Client getClient() {
		return client;
	}



	/**
	 * @param channel the channel to set
	 */
	public void setChannel(Channel channel) {
		this.channel = channel;
	}



	/**
	 * @return the channel
	 */
	public Channel getChannel() {
		return channel;
	}

	public boolean isConnected() {
		return isConnected;
	}
	public void setConnected(boolean isConnected) {
		this.isConnected = isConnected;
	}

}
